package co.edu.unal.bioingenium.kbmed.knowledge.snomed.util.io;

import co.edu.unal.bioingenium.kbmed.knowledge.KnowledgeSourceMetaData;
import co.edu.unal.bioingenium.kbmed.knowledge.dao.KnowledgeSourceDAO;
import co.edu.unal.bioingenium.kbmed.knowledge.dao.KnowledgeSourceDAOFactory;
import co.edu.unal.bioingenium.kbmed.knowledge.snomed.SnomedMetaData;
import co.edu.unal.bioingenium.kbmed.knowledge.snomed.vo.SnomedConcept;
import co.edu.unal.bioingenium.kbmed.knowledge.snomed.vo.SnomedDescriptor;
import co.edu.unal.bioingenium.kbmed.knowledge.snomed.vo.SnomedRelationship;
import co.edu.unal.bioingenium.kbmed.text.filter.FilterPipe;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Alejandro Riveros Cruz
 */
public class SnomedLoader {

    private static FilterPipe filterPipe = new FilterPipe();

    /**
     * 
     * @param file
     */
    public static void loadConcepts(String file) {
        try {
            System.out.println("loadConcepts");
            KnowledgeSourceDAO knowledgeSourceDAO = KnowledgeSourceDAOFactory.getKnowledgeSourceDAO();
            BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
            String line;
            String[] fields;
            String category;
            int count = 0;
            int i = 0;
            int ini, end;
            short numTokens;
            SnomedConcept snomedConcept = new SnomedConcept();
            Set<String> categoriesEN = SnomedConcept.CATEGORIES_EN;
            while ((line = bufferedReader.readLine()) != null) {
                fields = line.split("\t");
                ini = 0;
                end = fields[2].length();
                if (fields[2].endsWith(")")) {
                    ini = fields[2].lastIndexOf("(") + 1;
                    end = fields[2].lastIndexOf(")");
                    category = fields[2].substring(ini, end);
                    if (!categoriesEN.contains(category)) {
                        category = "unknow";
                        count++;
                    }
                } else {
                    category = "unknow";
                    count++;
                }
                snomedConcept.setConceptId(fields[0]);
                snomedConcept.setStatus(Byte.parseByte(fields[1]));
                snomedConcept.setDescription(fields[2]);
                numTokens = filterPipe.countTokens(snomedConcept.getDescription());
                snomedConcept.setNumTokens(numTokens);
                snomedConcept.setCTV3ID(fields[3]);
                snomedConcept.setSNOMEDID(fields[4]);
                snomedConcept.setIsPrimitive(Byte.parseByte(fields[5]));
                snomedConcept.setCategory(category);
                knowledgeSourceDAO.insertConcept(snomedConcept);
                i++;
            }
            bufferedReader.close();
            System.out.println(count + " concepts without category.");
            System.out.println(i + " concepts loaded.");
        } catch (IOException ex) {
            Logger.getLogger(SnomedLoader.class.getName()).log(Level.SEVERE, "Error while read the concept file.", ex);
        }
    }

    /**
     * 
     * @param file
     */
    public static void loadDescriptions(String file) {
        try {
            System.out.println("loadDescriptions");
            KnowledgeSourceDAO knowledgeSourceDAO = KnowledgeSourceDAOFactory.getKnowledgeSourceDAO();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF8"));
            String line;
            String[] fields;
            String category;
            int count = 0;
            int i = 0;
            int ini, end;
            short numTokens;
            Set<String> categoriesES = SnomedConcept.CATEGORIES_ES;
            SnomedDescriptor snomedDescriptor = new SnomedDescriptor();
            while ((line = bufferedReader.readLine()) != null) {
                fields = line.split("\t");
                ini = 0;
                end = fields[3].length();
                if (fields[3].endsWith(")")) {
                    ini = fields[3].lastIndexOf("(") + 1;
                    end = fields[3].lastIndexOf(")");
                    category = fields[3].substring(ini, end);
                    if (!categoriesES.contains(category)) {
                        snomedDescriptor.setTerm(fields[3]);
                        category = "unknow";
                        count++;
                    } else {
                        snomedDescriptor.setTerm(fields[3].substring(0, ini - 1));
                    }
                } else {
                    snomedDescriptor.setTerm(fields[3]);
                    category = "unknow";
                    count++;
                }
//                numTokens = (short) snomedDescriptor.getTerm().trim().split(" ").length;
                numTokens = (short) filterPipe.filter(snomedDescriptor.getTerm()).size();
                snomedDescriptor.setNumTokens(numTokens);
                snomedDescriptor.setDescriptionId(fields[0]);
                snomedDescriptor.setStatus(Byte.parseByte(fields[1]));
                snomedDescriptor.setConceptId(fields[2]);
                //snomedDescriptor.setTerm(fields[3]);
                snomedDescriptor.setInitialCapitalStatus(Boolean.parseBoolean(fields[4]));
                snomedDescriptor.setDescriptionType(Byte.parseByte(fields[5]));
                snomedDescriptor.setLanguageCode(fields[6]);
                knowledgeSourceDAO.insertDescriptor(snomedDescriptor);
                i++;
            }
            bufferedReader.close();
            System.out.println(count + " descriptors without category.");
            System.out.println(i + " descriptions loaded.");
        } catch (IOException ex) {
            Logger.getLogger(SnomedLoader.class.getName()).log(Level.SEVERE, "Error while load descriptor file.", ex);
        }
    }

    /**
     * 
     * @param file
     */
    public static void loadRelationships(String file) {
        try {
            System.out.println("loadRelationships");
            KnowledgeSourceDAO knowledgeSourceDAO = KnowledgeSourceDAOFactory.getKnowledgeSourceDAO();
            BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
            String line;
            String[] fields;
            int i = 0;
            SnomedRelationship snomedRelationship;
            while ((line = bufferedReader.readLine()) != null) {
                fields = line.split("\t");
                snomedRelationship = new SnomedRelationship();
                snomedRelationship.setRelationshipID(fields[0]);
                snomedRelationship.setConceptID1(fields[1]);
                snomedRelationship.setRelationshipType(fields[2]);
                snomedRelationship.setConceptID2(fields[3]);
                snomedRelationship.setCharacteristicType(Byte.parseByte(fields[4]));
                snomedRelationship.setRefinability(Byte.parseByte(fields[5]));
                snomedRelationship.setRelationshipGroup(Byte.parseByte(fields[6]));
                knowledgeSourceDAO.insertRelationShip(snomedRelationship);
                i++;
            }
            bufferedReader.close();
            System.out.println(i + " relationship loaded.");
        } catch (IOException ex) {
            Logger.getLogger(SnomedLoader.class.getName()).log(Level.SEVERE, "Error while load relationships file.", ex);
        }
    }

    /**
     * 
     * @param args
     */
    public static void main(String[] args) {
        KnowledgeSourceMetaData.setKnowledgeSourceMetaDataProvider(new SnomedMetaData());
        loadConcepts("/media/tera/thesis-data/SNOMED CT/sct1_Concepts_Core_INT_20100731.txt");
        loadDescriptions("/media/tera/thesis-data/SNOMED CT/sct1_Descriptions_es_INT_20101031.txt");
        loadRelationships("/media/tera/thesis-data/SNOMED CT/sct1_Relationships_Core_INT_20100731.txt");
    }
}
